<?php

namespace app\services;

use app\payment\PayFactory;
use plugin\admin\app\model\Notice;
use plugin\admin\app\model\Order;
use plugin\admin\app\model\TransferJob;
use plugin\admin\app\model\User;
use plugin\admin\app\model\UserCompany;
use plugin\admin\app\model\UserCompanyProduct;
use plugin\admin\app\model\UserPropertyLog;

class UserCompanyService
{
    /**
     * 获取公司列表（分页）
     *
     * @param int $page 页码
     * @param int $pageSize 每页记录数
     * @param string|null $keyword 搜索关键词
     * @return array
     */
    public static function getCompanyList(int $page, int $pageSize, ?string $keyword = null): array
    {
        $query = UserCompany::query()
            ->select(['id', 'user_id', 'company_logo', 'company_name', 'count']);

        // 如果有关键词，添加模糊搜索条件
        if (!empty($keyword)) {
            $query->where('company_name', 'like', '%' . $keyword . '%');
        }

        $offset = ($page - 1) * $pageSize;
        $total = $query->count(); // 获取总记录数

        $companies = $query->offset($offset)
            ->limit($pageSize)
            ->orderBy('id', 'desc')
            ->get()
            ->toArray();

        foreach ($companies as &$company) {
            $company['company_logo'] = full_url($company['company_logo']);
        }

        return [
            'list' => $companies,
            'pagination' => [
                'current_page' => $page,
                'page_size' => $pageSize,
                'total' => $total,
                'total_pages' => ceil($total / $pageSize),
            ],
        ];
    }

    public static function getCompanyDetail($id)
    {
        $company = UserCompany::query()
            ->where('user_id', $id)
            ->select(['id', 'user_id', 'company_logo', 'company_name', 'count'])
            ->first();

        if (!$company) {
            throw new \Exception('Company not found');
        }

        $company['company_logo'] = full_url($company['company_logo']);

        return $company;
    }

    public static function searchProductsByCompanyAndFileName(string $companyName, string $fileName, int $page, int $pageSize): array
    {
        // Find the company by name
        $company = UserCompany::query()
            ->select('user_id');

        if (!empty($companyName)) {
            $company->where('company_name', 'like', '%' . $companyName . '%');
        }

        $companies = $company->get()->toArray();

        // If no company is found, return an empty result
        if (!$companies) {
            return [
                'list' => [],
                'pagination' => [
                    'current_page' => $page,
                    'page_size' => $pageSize,
                    'total' => 0,
                    'total_pages' => 0,
                ],
            ];
        }

        $companyIds = array_column($companies, 'user_id');

        // Search for products by company_id and file_name
        $query = UserCompanyProduct::query()
            ->whereIn('company_id', $companyIds)
            ->select(['id', 'file_name', 'file_type', 'description', 'file_size', 'download_url']);

        if (!empty($fileName)) {
            $query->where('file_name', 'like', '%' . $fileName . '%');
        }

        $offset = ($page - 1) * $pageSize;
        $total = $query->count(); // Get the total number of records

        $products = $query->offset($offset)
            ->limit($pageSize)
            ->orderBy('id', 'desc')
            ->get()
            ->toArray();

        $productIds = array_column($products, 'id');
        $orders = Order::where('user_id', get_user_id())->whereIn('product_id', $productIds)->where('type', Order::TYPE_DOWNLOAD)->get()->toArray();

        foreach ($products as &$product) {
            $product['need_pay'] = 1;
            $product['pay_time'] = null;

            foreach ($orders as $order) {
                if ($order['product_id'] == $product['id']) {
                    $product['pay_time'] = $order['pay_time'];
                    break;
                }
            }

            $product['download_url'] = TransferService::getDownloadUrl2($product);
        }

        return [
            'list' => $products,
            'pagination' => [
                'current_page' => $page,
                'page_size' => $pageSize,
                'total' => $total,
                'total_pages' => ceil($total / $pageSize),
            ],
        ];
    }

    public static function searchProductsByCompanyIdAndFileName($companyId, $fileName, $fileTypes, $page, $pageSize): array
    {
        $query = UserCompanyProduct::query()
            ->where('company_id', $companyId)
            ->select(['id', 'file_name', 'file_type', 'description', 'file_size', 'download_url']);

        // If a keyword is provided, add a search condition
        if (!empty($fileName)) {
            $query->where('file_name', 'like', '%' . $fileName . '%');
        }

        // If a file type is provided, add a search condition
        if (!empty($fileTypes)) {
            $query->whereIn('file_type', $fileTypes);
        }

        $offset = ($page - 1) * $pageSize;
        $total = $query->count(); // Get the total number of records

        $products = $query->offset($offset)
            ->limit($pageSize)
            ->orderBy('id', 'desc')
            ->get()
            ->toArray();

        $productIds = array_column($products, 'id');
        $orders = Order::where('user_id', get_user_id())->whereIn('product_id', $productIds)->where('type', Order::TYPE_DOWNLOAD)->get()->toArray();

        foreach ($products as &$product) {
            $product['need_pay'] = 1;
            $product['pay_time'] = null;

            foreach ($orders as $order) {
                if ($order['product_id'] == $product['id']) {
                    $product['pay_time'] = $order['pay_time'];
                    break;
                }
            }

            $product['download_url'] = TransferService::getDownloadUrl2($product);
        }

        return [
            'list' => $products,
            'pagination' => [
                'current_page' => $page,
                'page_size' => $pageSize,
                'total' => $total,
                'total_pages' => ceil($total / $pageSize),
            ],
        ];
    }


    public static function getCompanyProducts(int $companyId, int $page, int $pageSize, ?string $keyword = null): array
    {

        $query = UserCompanyProduct::query()
            ->where('company_id', $companyId)
            ->select(['id', 'file_name', 'file_type', 'description', 'file_size', 'download_url']);

        // If a keyword is provided, add a search condition
        if (!empty($keyword)) {
            $query->where('file_name', 'like', '%' . $keyword . '%');
        }

        $offset = ($page - 1) * $pageSize;
        $total = $query->count(); // Get the total number of records

        $products = $query->offset($offset)
            ->limit($pageSize)
            ->orderBy('id', 'desc')
            ->get()
            ->toArray();

        return [
            'list' => $products,
            'pagination' => [
                'current_page' => $page,
                'page_size' => $pageSize,
                'total' => $total,
                'total_pages' => ceil($total / $pageSize),
            ],
        ];
    }

    public static function createOrder($product_id, $payWay, $payWayType = 'h5')
    {
        $user = User::where('id', get_user_id())->first();
        // Generate a unique order number
        $orderNo = OrderService::generateOrderNo();

        // Create the order
        $orderData = [
            'order_no' => $orderNo,
            'user_id' => get_user_id(),
            'price' => ConfigService::get('need_pay_point'), // Example price for upgrading membership
            'type' => Order::TYPE_DOWNLOAD,
            'pay_way' => $payWay,
            'pay_way_type' => $payWayType,
            'status' => Order::STATUS_WAITING_PAY,
            'created_time' => date('Y-m-d H:i:s'),
            'product_id' => $product_id
        ];
        Order::insert($orderData);

        // Prepare the response
        $response = ['order_no' => $orderNo];

        // If payment method is WeChat, generate WeChat payment parameters
        if ($payWay === Order::PAY_TYPE_WECHAT) {
            $paymentParams = PayFactory::create($payWay)->setData([
                'pay_way_type' => $payWayType,
                'order_no' => $orderNo,
                'total_amount' => $orderData['price'],
            ])->pay();

            $response['payment_params'] = $paymentParams;
        } elseif ($payWay === Order::PAY_TYPE_BALANCE) {
            PayFactory::create($payWay)->setData([
                'order_no' => $orderNo,
                'total_amount' => $orderData['price'],
                'source' => UserPropertyLog::PAY_ORDER
            ])->pay();
        }

        if ($payWay == Order::PAY_TYPE_BALANCE) {
            self::paySuccess($orderNo);
        }

        return $response;
    }

    public static function paySuccess($orderNo)
    {
        $order = Order::where('order_no', $orderNo)->first();

        $dateTime = date('Y-m-d H:i:s');

        $order->status = Order::STATUS_FINISH;
        $order->pay_time = $dateTime;
        $order->save();

        $job = UserCompanyProduct::where('id', $order['product_id'])->first();

        Notice::add($order['user_id'], '下载支付', sprintf("您已成功支付¥%.2f，可下载《%s》", $order['price'], $job['file_name']), Notice::TYPE_PAYMENT_DOWNLOAD, $job['id']);
    }

    public static function getCompanyProduct($id)
    {
        $data = UserCompanyProduct::query()
            ->where('id', $id)
            ->select(['id', 'file_name', 'company_id', 'file_type', 'description', 'file_size', 'download_url'])->first();

        $order = Order::where('user_id', get_user_id())->where('product_id', $id)->where('type', Order::TYPE_DOWNLOAD)->orderByDesc('id')->first();

        if ($order) {
            $data['pay_time'] = $order->pay_time;
        } else {
            $data['pay_time'] = null;
        }

        $company = UserCompany::where('user_id', $data['company_id'])->first();

        if ($company['user_id'] == get_user_id()) {
            $data['need_pay'] = 0;
        } else {
            if (UserService::isVip(get_user_id())) {
                $data['need_pay'] = 0;
            } else {
                $data['need_pay'] = 1;
            }
        }

        $data['download_url'] = TransferService::getDownloadUrl2($data);

        return $data;
    }

    public static function editProduct($id, $data)
    {
        $product = UserCompanyProduct::where('company_id', get_user_id())->where('id', $id)->first();

        if (!$product) {
            throw new \Exception('Product not found');
        }

        $product->file_name = $data['file_name'];
        $product->description = $data['description'];

        if (!$product->save()) {
            throw new \Exception('Failed to update product');
        }
    }

    public static function delProduct($id)
    {
        $product = UserCompanyProduct::where('company_id', get_user_id())->where('id', $id)->first();

        if (!$product) {
            throw new \Exception('Product not found');
        }

        if (!$product->delete()) {
            throw new \Exception('Failed to delete product');
        }

        UserCompany::where('user_id', get_user_id())->decrement('count', 1);
    }

    public static function getProductList($page = 1, $length = 10, $keyword = '', $fileType = 'all')
    {
        $query = UserCompanyProduct::query()
            ->where('company_id', get_user_id())
            ->select(['id', 'file_name', 'file_type', 'description', 'file_size', 'download_url', 'created_time']);

        if (!empty($keyword)) {
            $query->where('file_name', 'like', '%' . $keyword . '%');
        }

        if ($fileType !== 'all') {
            $query->where('file_type', $fileType);
        }

        $offset = ($page - 1) * $length;
        $total = $query->count(); // Get the total number of records

        // 打印 SQL 语句和绑定参数
        dump($query->toSql());
        dump($query->getBindings());


        $products = $query->offset($offset)
            ->limit($length)
            ->orderBy('id', 'desc')
            ->get()
            ->toArray();

        return [
            'list' => $products,
            'pagination' => [
                'current_page' => $page,
                'page_size' => $length,
                'total' => $total,
                'total_pages' => ceil($total / $length),
            ],
        ];
    }

    public static function batchAddProducts(array $products): void
    {
        $data = [];

        foreach ($products as $product) {
            $data[] = [
                'company_id' => get_user_id(),
                'file_name' => $product['file_name'],
                'file_type' => $product['file_type'],
                'description' => $product['description'],
                'file_size' => $product['file_size'],
                'download_url' => $product['download_url'],
                'created_time' => date('Y-m-d H:i:s')
            ];
        }

        UserCompanyProduct::insert($data);
        UserCompany::where('user_id', get_user_id())->increment('count', count($data));
    }
}